/*
 *  Parser.cpp
 *  Compiler
 *
 *  Created by Jacopo De Stefani on 2/14/12.
 *  Copyright 2012 Politecnico di Milano. All rights reserved.
 *
 */

#include "Scanner.h"
#include "Writer.h"
#include <iostream>
#include <stdio.h>

using namespace std;

enum Keywords {INTEGER,
			   BOOLEAN,
			   LT,
			   GT,
			   LE,
			   GE,
	           EQ,
			   NE,
			   AND,
	           OR,
			   NOT,
	           PLUS,
			   MINUS,
	           DIV,
	           MUL,
	           TRUEB,
	           FALSEB,
	           WRITE,
	           READ,
	           PRG_INIT,
			   PRG_END,
			   FUN,
	           PROC,
	           BLK_INIT,
	           BLK_END,
	           WHILE,
	           DO,
	           IF,
	           THEN,
	           ELSE,
	           VAR,
	           ID,
			   NUM,
	           ASSIGN,
	           COMM_INIT,
	           COMM_END,
	           TYPE_SEP,
	           ISTR_SEP,
			   EXPR_SEP,
	           LST_INIT,
	           LST_END,
	           ENDFILE};


bool match(Keywords);
bool programP(void);
bool varsP(void);
bool idlistP(void);
bool idlist1P(void);
bool typeP(void);
bool routinelistP(void);
bool routineP(void);
bool functionP(void);
bool procedureP(void);
bool argsoptP(void);
bool argsP(void);
bool args1P(void);
bool blockP(void);
bool statementoptP(void);
bool statementlistP(void);
bool stlist1P(void);
bool statementP(void);
bool stcontP(void);
bool callexpP(void);
bool c1P(void);
bool c2P(void);
bool tP(void);
bool c3P(void);
bool c4P(void);
bool fP(void);
bool c5P(void);
bool c6P(void);
bool gP(void);
bool expressionlistP(void);
bool exlist1P(void);
bool expressionP(void);

//Read only global variable
Keywords currTok;

int main(int argv, char** argc){
	printf("Hello, I'm a scanner!");
	//Look at this! A comment!
	getchar();
	return 0;
}

//Match function checks if the expected token
//from the parser equals the next scanned token.
bool match(Keywords matchTok){
	
	//Check and integrate with parser
	if (currTok == matchTok) {
		//currTok = parser.getnextsym();
		return true;
	}
	
	return false;
	
}

bool programP(void){
	switch (currTok) {
		//Production 1 - program ID ; <VARS> <ROUTINELIST> <BLOCK> . $
		case PRG_INIT:
			
			if(match(PRG_INIT) == false){
				cerr << "Program keyword missing.\n";
				return false;
			}
			
			//TO DO : Program identifier check
			if(match(ID) == false){
				cerr << "Program identifier missing.\n";
				return false;
			}	
			
			
			if(match(ISTR_SEP) == false){
				cerr << "; missing.\n";
				return false;
			}			
			
			if(varsP() == false){
				return false;
			}
			
			Writer::getInstance()->uncondJumpTo("@main");
			
			if(routinelistP() == false){
				return false;
			}
			
			Writer::getInstance()->defLabel("@main");
			
			if(blockP()== false){
				return false;
			}
			
			if(match(PRG_END) == false){
				cerr << ". missing.\n";
				return false;
			}
			
			Writer::getInstance()->endProg();
			
			break;
		
		default:
			return false;
	}
	
	return true;
}

bool varsP(void){
	switch (currTok) {
		//Production 2 - var <IDLIST> : <TYPE> ; <VARS>
		case VAR:
			
			if(match(VAR) == false){
				cerr << "var keyword missing.\n";
				return false;
			}
			
			if(idlistP() == false){
				return false;
			}
			
			if(match(TYPE_SEP) == false){
				cerr << ": missing.\n";
				return false;
			}			
			
			if(typeP() == false){
				return false;
			}
			
			if(match(ISTR_SEP) == false){
				cerr << "; missing.\n";
				return false;
			}			
			
			if(varsP()== false){
				return false;
			}
			break;
		
		//Production 3 - ε
		case FUN:
		case PROC:
		case BLK_INIT:
			//Code to execute
			break;

		default:
			return false;
	}
	
	return true;
}

bool idlistP(void){
	switch (currTok) {
			//Production 4 - ID<IDLIST1>
		case ID:
			//TO DO : Variable checks?
			if(match(ID) == false){
				cerr << "Variable identifier missing.\n";
				return false;
			}
			
			if(idlist1P() == false){
				return false;
			}
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool idlist1P(void){
	switch (currTok) {
		
		//Production 5 - ,<IDLIST>
		case EXPR_SEP:
			if(match(EXPR_SEP) == false){
				cerr << ", missing.\n";
				return false;
			}
			
			if(idlistP() == false){
				return false;
			}
			break;
		
		//Production 6 - ε
		case TYPE_SEP:
			//Code to execute
			break;
			
			
		default:
			return false;
	}
	
	return true;
}

bool typeP(void){
	switch (currTok) {
		//Production 7 - integer
		case INTEGER:
			if(match(INTEGER) == false){
				cerr << "integer keyword missing.\n";
				return false;
			}
			break;
			
			
		//Production 8 - boolean
		case BOOLEAN:
			if(match(BOOLEAN) == false){
				cerr << "boolean keyword missing.\n";
				return false;
			}
			break;
			
			
		default:
			return false;
	}
	
	return true;
}

bool routinelistP(void){
	
	switch (currTok) {
		//Production 9 - <ROUTINE> ; <ROUTINELIST>
		case FUN:
		case PROC:
			
			if(routineP() == false){
				return false;
			}
			
			if(match(ISTR_SEP) == false){
				cerr << "; missing.\n";
				return false;
			}
			
			if(routinelistP() == false){
				return false;
			}
			
			break;
			
			
		//Production 10  - ε
		case BLK_INIT:
			//Code to execute
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool routineP(void){
	
	switch (currTok) {
		
		//Production 11 - <FUNCTION>
		case FUN:
			
			if(functionP() == false){
				return false;
			}
			
			break;
		
		//Production 12 - <PROCEDURE>
		case PROC:
			
			if(procedureP() == false){
				return false;
			}
			
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool functionP(void){
	
	switch (currTok) {
			
		//Production 13 - function ID <ARGSOPT> : <TYPE> ; <VARS> <BLOCK>
		case FUN:
			
			if(match(FUN) == false){
				cerr << "function keyword missing.\n";
				return false;
			}
			
			//TO DO : Program identifier check
			if(match(ID) == false){
				cerr << "function identifier missing.\n";
				return false;
			}	
			
			if(argsoptP() == false){
				return false;
			}
			
			if(match(TYPE_SEP) == false){
				cerr << ": missing.\n";
				return false;
			}			
			
			if(typeP() == false){
				return false;
			}
			
			if(match(ISTR_SEP) == false){
				cerr << "; missing.\n";
				return false;
			}	
			
			if(varsP() == false){
				return false;
			}
			
			
			if(blockP()== false){
				return false;
			}
			
			Writer::getInstance()->retFunc();
			
			break;
			
			
			
		default:
			return false;
	}
	
	return true;
}

bool procedureP(void){
	
	switch (currTok) {
		
		//Production 14 - procedure ID <ARGSOPT> ; <VARS> <BLOCK>
		case PROC:
			
			if(match(PROC) == false){
				cerr << "procedure keyword missing.\n";
				return false;
			}
			
			//TO DO : Program identifier check
			if(match(ID) == false){
				cerr << "procedure identifier missing.\n";
				return false;
			}	
			
			if(argsoptP() == false){
				return false;
			}
			
			if(match(ISTR_SEP) == false){
				cerr << "; missing.\n";
				return false;
			}	
			
			if(varsP() == false){
				return false;
			}
			
			
			if(blockP()== false){
				return false;
			}
			
			Writer::getInstance()->retProc();
			
			break;
			
			
		default:
			return false;
	}
	
	return true;
}

bool argsoptP(void){
	
	switch (currTok) {
		//Production 15 - ( var <ARGS> )
		case LST_INIT:
			
			if(match(LST_INIT) == false){
				cerr << "( missing.\n";
				return false;
			}
			
			if(match(VAR) == false){
				cerr << "var keyword missing.\n";
				return false;
			}
			
			
			if(argsP() == false){
				return false;
			}
			
			if(match(LST_END) == false){
				cerr << ") missing.\n";
				return false;
			}
			
			break;
			
			
		//Production 16  - ε
		case TYPE_SEP:
		case ISTR_SEP:
			//Code to execute
			break;
			
		default:
			return false;
	}
	
	return true;
}


bool argsP(void){
	
	switch (currTok) {
			//Production 17 - <IDLIST> : <TYPE><ARGS1>
		case ID:
			
			if(idlistP() == false){
				return false;
			}
			
			if(match(TYPE_SEP) == false){
				cerr << ": missing.\n";
				return false;
			}
			
			
			if(typeP() == false){
				return false;
			}
			
			if(args1P() == false){
				return false;
			}
			
			break;
				
		default:
			return false;
	}
	
	return true;
}

bool args1P(void){
	
	switch (currTok) {
		//Production 18 - ; <ARGS>
		case ISTR_SEP:
			
			if(match(ISTR_SEP) == false){
				cerr << "; missing.\n";
				return false;
			}
			
			if(argsP() == false){
				return false;
			}
			
			break;
			
			
		//Production 19  - ε
		case LST_END:
			//Code to execute
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool blockP(void){
	
	switch (currTok) {
		
		//Production 20 - begin <STATEMENTOPT> end
		case BLK_INIT:
			
			if(match(BLK_INIT) == false){
				cerr << "begin keyword missing.\n";
				return false;
			}
		
			if(statementoptP() == false){
				return false;
			}
			
			if(match(BLK_END) == false){
				cerr << "end keyword missing.\n";
				return false;
			}
			
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool statementoptP(void){
	
	switch (currTok) {
		
		//Production 21 - <STATEMENTLIST>
		case ID:
		case BLK_INIT:
		case IF:
		case WHILE:
		case READ:
		case WRITE:
			
			if(statementlistP() == false){
				return false;
			}
			
			break;
			
			
		//Production 22  - ε
		case BLK_END:
			//Code to execute
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool statementlistP(void){
	
	switch (currTok) {
		//Production 23 - <STATEMENT><STLIST1>
		case ID:
		case BLK_INIT:
		case IF:
		case WHILE:
		case READ:
		case WRITE:
			
			if(statementP() == false){
				return false;
			}
			
			if(stlist1P() == false){
				return false;
			}
			
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool stlist1P(void){
	
	switch (currTok) {
			
		//Production 24 - ; <STATEMENTLIST>
		case ISTR_SEP:
			
			if(match(ISTR_SEP) == false){
				cerr << "; missing.\n";
				return false;
			}
			
			if(statementlistP() == false){
				return false;
			}
			
			break;
			
			
		//Production 25  - ε
		case BLK_END:
			//Code to execute
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool statementP(void){
	
	switch (currTok) {
			
		//Production 26 - ID<STCONT> 
		case ID:
			
			if(match(ID) == false){
				cerr << "identifier missing.\n";
				return false;
			}
			
			if(stcontP() == false){
				return false;
			}
			
			break;
		
		//Production 27 - <BLOCK>
		case BLK_INIT:
			
			if(blockP() == false){
				return false;
			}
			
			break;
		
		//Production 28 - if <EXPRESSION> then <STATEMENT> else <STATEMENT>
		case IF:
			
			Writer::getInstance()->setIfCtr(Writer::getInstance()->getIfCtr()+1);
			
			if(match(IF) == false){
				cerr << "if keyword missing.\n";
				return false;
			}
			
			
			
			if(expressionP() == false){
				return false;
			}
			
			Writer::getInstance()->condFalseJumpTo("else_"+Writer::getInstance()->getIfCtr());
			
			if(match(THEN) == false){
				cerr << "then keyword missing.\n";
				return false;
			}
			
			if(statementP() == false){
				return false;
			}
			
			Writer::getInstance()->uncondJumpTo("afterelse_"+Writer::getInstance()->getIfCtr());
			Writer::getInstance()->defLabel("else_"+Writer::getInstance()->getIfCtr());
			
			if(match(ELSE) == false){
				cerr << "else keyword missing.\n";
				return false;
			}
			
			if(statementP() == false){
				return false;
			}
			
			Writer::getInstance()->defLabel("afterelse_"+Writer::getInstance()->getIfCtr());
			
			break;
		
		//Production 29 - while <EXPRESSION> do <STATEMENT> 
		case WHILE:
			
			Writer::getInstance()->setLoopCtr(Writer::getInstance()->getLoopCtr()+1);
			
			if(match(WHILE) == false){
				cerr << "while keyword missing.\n";
				return false;
			}
			
			Writer::getInstance()->defLabel("loop_"+Writer::getInstance()->getLoopCtr());
			
			if(expressionP() == false){
				return false;
			}
			
			Writer::getInstance()->condFalseJumpTo("exit_"+Writer::getInstance()->getLoopCtr());
			
			if(match(DO) == false){
				cerr << "do keyword missing.\n";
				return false;
			}
			
			if(statementP() == false){
				return false;
			}
			
			Writer::getInstance()->uncondJumpTo("loop_"+Writer::getInstance()->getLoopCtr());
			Writer::getInstance()->defLabel("exit_"+Writer::getInstance()->getLoopCtr());
			
			break;
		
		//Production 30 - read(ID) 
		case READ:
			
			if(match(READ) == false){
				cerr << "while keyword missing.\n";
				return false;
			}
			
			if(match(LST_INIT) == false){
				cerr << "( missing.\n";
				return false;
			}
			
			if(match(ID) == false){
				cerr << "identifier missing.\n";
				return false;
			}
			
			if(match(LST_END) == false){
				cerr << ") missing.\n";
				return false;
			}
			
			break;
			
		//Production 31 - write ( <EXPRESSION> )
		case WRITE:
			
			if(match(WRITE) == false){
				cerr << "while keyword missing.\n";
				return false;
			}
			
			if(match(LST_INIT) == false){
				cerr << "( missing.\n";
				return false;
			}
			
			if(expressionP() == false){
				return false;
			}
			
			if(match(LST_END) == false){
				cerr << ") missing.\n";
				return false;
			}
			
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool stcontP(void){
	
	switch (currTok) {
			
		//Production 32 - :=<EXPRESSION>
		case ASSIGN:
			
			if(match(ASSIGN) == false){
				cerr << ":= missing.\n";
				return false;
			}
			
			if(expressionP() == false){
				return false;
			}
			
			break;
			
			
		//Production 33  - <CALLEXP>
		case LST_INIT:
			
			if(callexpP() == false){
				return false;
			}
			
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool callexpP(void){
	
	switch (currTok) {
		//Production 34 - ( <EXPRESSIONLIST> )
		case LST_INIT:
			
			if(match(LST_INIT) == false){
				cerr << "( missing.\n";
				return false;
			}
			
			if(expressionlistP() == false){
				return false;
			}
			
			if(match(LST_END) == false){
				cerr << ") missing.\n";
				return false;
			}
			
			break;
			
			
		//Production 35  - ε
		case GT:
		case LT:
		case GE:
		case LE:
		case EQ:
		case NE:
		case LST_END:
		case BLK_END:
		case THEN:
		case DO:
			//Code to execute
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool expressionlistP(void){
	
	switch (currTok) {
		//Production 36 - <EXPRESSION><EXLIST1>
		case ID:
		case NUM:
		case TRUEB:
		case FALSEB:
		case BLK_INIT:
		case MINUS:
		case NOT:
			
			if(expressionP() == false){
				return false;
			}
			
			if(exlist1P() == false){
				return false;
			}
			
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool exlist1P(void){
	
	switch (currTok) {
			
		//Production 37 - , <EXPRESSIONLIST>
		case EXPR_SEP:
			
			if(match(EXPR_SEP) == false){
				cerr << ", missing.\n";
				return false;
			}
			
			if(expressionP() == false){
				return false;
			}
			
			break;
			
			
		//Production 38  - ε
		case LST_END:
			//Code to execute
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool expressionP(void){
	
	switch (currTok) {
		//Production 39 - <C1><C2>
		case ID:
		case NUM:
		case TRUEB:
		case FALSEB:
		case BLK_INIT:
		case MINUS:
		case NOT:
			
			if(c1P() == false){
				return false;
			}
			
			if(c2P() == false){
				return false;
			}
			
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool c1P(void){
	
	switch (currTok) {
		//Production 40 - <C1>
		case ID:
		case NUM:
		case TRUEB:
		case FALSEB:
		case BLK_INIT:
		case MINUS:
		case NOT:
			
			if(c1P() == false){
				return false;
			}
			
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool c2P(void){
	
	switch (currTok) {
		//Production 41 - ><T><C2>
		case GT:
			
			if(match(GT) == false){
				cerr << "> missing.\n";
				return false;
			}
			
			if(tP() == false){
				return false;
			}
			
			Writer::getInstance()->grtTop2();
			
			if(c2P() == false){
				return false;
			}
			
			break;
		
		//Production 42 - <<T><C2>
		case LT:
			
			if(match(LT) == false){
				cerr << "< missing.\n";
				return false;
			}
			
			if(tP() == false){
				return false;
			}
			
			Writer::getInstance()->lesTop2();
			
			if(c2P() == false){
				return false;
			}
			
			break;
		
		//Production 43 - >=<T><C2>
		case GE:
			
			if(match(GE) == false){
				cerr << ">= missing.\n";
				return false;
			}
			
			if(tP() == false){
				return false;
			}
			
			Writer::getInstance()->geqTop2();
			
			if(c2P() == false){
				return false;
			}
			
			break;
		
		//Production 44 - <=<T><C2>
		case LE:
			
			if(match(LE) == false){
				cerr << "<= missing.\n";
				return false;
			}
			
			if(tP() == false){
				return false;
			}
			
			Writer::getInstance()->leqTop2();
			
			if(c2P() == false){
				return false;
			}
			
			break;
		
		//Production 45 - <><T><C2>
		case NE:
			
			if(match(NE) == false){
				cerr << "<> missing.\n";
				return false;
			}
			
			if(tP() == false){
				return false;
			}
			
			Writer::getInstance()->neqTop2();
			
			if(c2P() == false){
				return false;
			}
			
			break;
		
		//Production 46 - =<T><C2>
		case EQ:
			
			if(match(EQ) == false){
				cerr << "= missing.\n";
				return false;
			}
			
			if(tP() == false){
				return false;
			}
			
			Writer::getInstance()->neqTop2();
			
			if(c2P() == false){
				return false;
			}
			
			break;
		
		//Production 47  - ε
		case EXPR_SEP:
		case ISTR_SEP:
		case LST_END:
		case DO:
		case THEN:
		case BLK_END:
			//Code to execute
			break;
			
		default:
			return false;
	}
	
	
	
	return true;
}


bool tP(void){
	
	switch (currTok) {
		//Production 48 - <C3><C4>
		case ID:
		case NUM:
		case TRUEB:
		case FALSEB:
		case BLK_INIT:
		case MINUS:
		case NOT:
			
			if(c3P() == false){
				return false;
			}
			
			if(c4P() == false){
				return false;
			}
			
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool c3P(void){
	
	switch (currTok) {
		//Production 49 - <C3>
		case ID:
		case NUM:
		case TRUEB:
		case FALSEB:
		case BLK_INIT:
		case MINUS:
		case NOT:
			
			if(c3P() == false){
				return false;
			}
			
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool c4P(void){
	
	switch (currTok) {
		//Production 50 - +<F><C4>
		case PLUS:
			
			if(match(PLUS) == false){
				cerr << "+ missing.\n";
				return false;
			}
			
			if(fP() == false){
				return false;
			}
			
			Writer::getInstance()->addTop2();
			
			if(c4P() == false){
				return false;
			}
			
			break;
			
		//Production 51 - or<F><C4>
		case OR:
			
			if(match(OR) == false){
				cerr << "or keyword missing.\n";
				return false;
			}
			
			if(fP() == false){
				return false;
			}
			
			Writer::getInstance()->orTop2();
			
			if(c4P() == false){
				return false;
			}
			
			break;
		
		//Production 52 - -<F><C4>
		case MINUS:
			
			if(match(MINUS) == false){
				cerr << "- missing.\n";
				return false;
			}
			
			if(fP() == false){
				return false;
			}
			
			Writer::getInstance()->subTop2();
			
			if(c4P() == false){
				return false;
			}
			
			break;
			
		
			
		//Production 53  - ε
		case GT:
		case LT:
		case GE:
		case LE:
		case EQ:
		case NE:
		case EXPR_SEP:
		case ISTR_SEP:
		case LST_END:
		case DO:
		case THEN:
		case BLK_END:
			//Code to execute
			break;
			
		default:
			return false;
	}
	
	
	
	return true;
}


bool fP(void){
	
	switch (currTok) {
		//Production 54 - <C5><C6>
		case ID:
		case NUM:
		case TRUEB:
		case FALSEB:
		case BLK_INIT:
		case MINUS:
		case NOT:
			
			if(c5P() == false){
				return false;
			}
			
			if(c6P() == false){
				return false;
			}
			
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool c5P(void){
	
	switch (currTok) {
		//Production 55 - <C5>
		case ID:
		case NUM:
		case TRUEB:
		case FALSEB:
		case BLK_INIT:
		case MINUS:
		case NOT:
			
			if(c5P() == false){
				return false;
			}
			break;
			
		default:
			return false;
	}
	
	return true;
}

bool c6P(void){
	
	switch (currTok) {
		//Production 56 - *<G><C6>
		case MUL:
			
			if(match(MUL) == false){
				cerr << "* missing.\n";
				return false;
			}
			
			if(gP() == false){
				return false;
			}
			
			Writer::getInstance()->mulTop2();
			
			if(c6P() == false){
				return false;
			}
			
			break;
			
		//Production 57 - and<G><C6>
		case AND:
			
			if(match(AND) == false){
				cerr << "and keyword missing.\n";
				return false;
			}
			
			if(gP() == false){
				return false;
			}
			
			Writer::getInstance()->andTop2();
			
			if(c6P() == false){
				return false;
			}
			
			break;
			
		//Production 58 - /<G><C6>
		case DIV:
			
			if(match(DIV) == false){
				cerr << "/ missing.\n";
				return false;
			}
			
			if(gP() == false){
				return false;
			}
			
			Writer::getInstance()->divTop2();
			
			if(c6P() == false){
				return false;
			}
			
			break;			
			
			
		//Production 59  - ε
		case PLUS:
		case MINUS:
		case OR:
		case GT:
		case LT:
		case GE:
		case LE:
		case EQ:
		case NE:
		case EXPR_SEP:
		case ISTR_SEP:
		case LST_END:
		case DO:
		case THEN:
		case BLK_END:
			//Code to execute
			break;
			
		default:
			return false;
	}
	
	
	
	return true;
}

bool gP(void){
	
	switch (currTok) {
		//Production 60 - -<G>
		case MINUS:
			
			if(match(MINUS) == false){
				cerr << "- missing.\n";
				return false;
			}
			
			if(gP() == false){
				return false;
			}
			
			//CHECK POSITION!!!!
			Writer::getInstance()->negTop();
			
			break;
			
		//Production 61 - not<G>
		case NOT:
			
			if(match(NOT) == false){
				cerr << "not keyword missing.\n";
				return false;
			}
			
			if(gP() == false){
				return false;
			}
			
			//CHECK POSITION!!!!
			Writer::getInstance()->notTop();
			
			
			break;
		
		//Production 62 - ID<CALLEXP>
		case ID:
			
			if(match(ID) == false){
				cerr << "identifier missing.\n";
				return false;
			}
			
			if(callexpP() == false){
				return false;
			}
			
			break;
		
		//Production 63 - NUM
		case NUM:
			
			if(match(NUM) == false){
				cerr << "numerical value missing.\n";
				return false;
			}
			
			break;
			
		//Production 64 - true
		case TRUEB:
			
			if(match(TRUEB) == false){
				cerr << "boolean value missing.\n";
				return false;
			}
			
			Writer::getInstance()->putBoolTop(true);
			
			
			break;
		
		//Production 65 - false
		case FALSEB:
			
			if(match(FALSEB) == false){
				cerr << "boolean value missing.\n";
				return false;
			}
			
			Writer::getInstance()->putBoolTop(false);
			
			break;
			
		//Production 66 - ( <EXPRESSION> )
		case LST_INIT:
			
			if(match(LST_INIT) == false){
				cerr << "( missing.\n";
				return false;
			}
			
			if(expressionP() == false){
				return false;
			}
			
			if(match(LST_END) == false){
				cerr << ") missing.\n";
				return false;
			}
			
			break;
			
		default:
			return false;
	}
	
	
	
	return true;
}
